fix: prune stale sessionData_* cookies and stop noisy parse log#554
fix: prune stale sessionData_* cookies and stop noisy parse log#554Vadman97 wants to merge 1 commit into
Conversation
setItem writes session data to both localStorage and cookies, but pruneSessionData only walked localStorage. As a result, sessionData_* cookies accumulated indefinitely whenever localStorage and cookies fell out of sync (cleared site data, subdomain mismatch, parallel tabs, etc.), eventually bloating the Cookie header enough to break unrelated API calls. Walk cookies too, fall back to sessionStartTime so sessions that ended before the first push still age out, and drop entries with no usable timestamp. The error-level "failed to parse session data" log fired on every page load when a cookie was truncated past 4KB — exactly the bloat scenario — so silently remove corrupt entries instead. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default mode and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 04514c3. Configure here.
| for (const key of candidates) { | ||
| let stale = true | ||
| try { | ||
| const sessionData = JSON.parse(getItem(key) || '{}') as SessionData |
There was a problem hiding this comment.
Cookie-only entries always treated as stale due to localStorage-only read
Medium Severity
The freshness check uses getItem(key) which only reads from getPersistentStorage() (localStorage), never from cookies. For entries discovered via cookieStorage.keys() that have no matching localStorage entry — the exact scenario this PR targets — getItem returns '', producing JSON.parse('{}') with no timestamps, so ts is always undefined and stale is always true. This means all cookie-only entries are unconditionally removed regardless of whether they contain fresh session data for an active parallel tab. The freshness check needs to fall back to cookieStorage.getItem(key) when getItem(key) returns empty.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 04514c3. Configure here.


Summary
A customer reported their cookies were full of
session*keys to the point where some services rejected API calls due to overly long context headers.Root cause:
setItemwrites session data to bothlocalStorageand cookies, butpruneSessionDataonly walkedlocalStorage. Whenever the two stores drifted (cleared site data, subdomain mismatch, parallel tabs, localStorage temporarily unavailable when written),sessionData_*cookies accumulated indefinitely and bloated theCookieheader until unrelated APIs started rejecting requests.Also fixes a noisy
error-level"failed to parse session data for key sessionData_..."log (the successor to the older"is not session data"log removed in #269). It fired on every page load whenever a cookie was truncated past the 4KB limit — exactly the bloat scenario.Changes
pruneSessionDatanow walks bothgetPersistentStorage()andcookieStorage.keys()and removes stale entries from whichever store holds them.sessionStartTimewhenlastPushTimeis absent, so sessions that ended before their first push still age out (previously they were pinned forever).CookieStorage.keys()for enumerating cookies viajs-cookie.Test plan
yarn run vitest run— 426 tests pass (existing 421 + 5 new)yarn format-checkcleanyarn turbo run enforce-size --filter highlight.run— 166.2 KB / 256 KBsessionData_*cookies are removed when a new session starts🤖 Generated with Claude Code